<?php

namespace App\Http\Controllers\VideoApi;

use App\Http\Config\ErrorCode;
use App\Library\UpTools;
use App\Models\video\BroadcasterModel;
use App\Models\video\CommentModel;
use App\Models\video\CommonServer;
use App\Models\video\CourseCatalogModel;
use App\Models\video\CourseCollectModel;
use App\Models\video\CourseModel;
use App\Models\video\CourseViewRecordModel;
use App\Models\video\DataCacheModel;
use App\Models\video\OrderModel;
use App\Models\video\ReplyModel;
use App\Models\video\VideoSettingModel;
use App\Models\video\VideoUserModel;
use App\Models\video\VodHandle;
use App\Models\video\VodVideoModel;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class UserCourseController extends BaseController
{
    public function __construct(Request $request)
    {
        $this->noCheckTokenAction = ['getCourseList', "getCourseDetail", 'getCourseCatalogList']; //不校验openid
        parent::__construct($request);
    }

    // 获取课程列表
    public function getCourseList(Request $request){
        if($this->returnData["code"] !== 0){
            return $this->return_result($this->returnData);
        }
        $filter = "c.status = 1 and c.mall_id = {$request->mallData["id"]}";
        $settingData = VideoSettingModel::getFields("operate_mode", ["mall_id" => $request->mallData["id"]]);
        if($settingData["operateMode"] == '1'){
            $broadcasterId = BroadcasterModel::getValue("id", ["mall_id" => $request->mallData["id"], "status" => 1]);
            $filter .= " and c.broadcaster_id = ".($broadcasterId ?: 0);
        }
        $page = $request->page ?: 1;
        $pageSize = $request->pageSize ?: 10;
        $db = CourseModel::query()->from(CourseModel::query()->getModel()->getTable()." as c")->whereRaw($filter);
        $data['count'] = $db->count();
        $data['currentPage'] = $page;
        $data['totalPage'] = ceil(($data['count'])/$pageSize);
        $subSql = CourseCatalogModel::query()->selectRaw("count(*)")->whereRaw("course_id = c.id and status = '1'")->toSql();
        $data["list"] = $db->select("c.id", "c.name", "c.broadcaster_id", "c.cover_img_id", "c.number", "c.pay_money")
            ->selectRaw("({$subSql}) as currentNum")
            ->orderBy("c.created_at", "desc")
            ->get()->toArray();
        if(!empty($data["list"])){
            $data["list"] = CourseModel::transferField($data["list"]);
            foreach ($data["list"] as &$item){
                $item["commentCount"] = CommentModel::getCount(["belong_id" => $item["id"], "type" => 2, "status" => 1, "mall_id" => $request->mallData["id"]]) +
                    ReplyModel::query()->from(ReplyModel::query()->getModel()->getTable() . " as r")
                        ->leftJoin(CommentModel::query()->getModel()->getTable() . " as c", "c.id", '=', "r.comment_id")
                        ->where(["c.belong_id" => $item["id"], "r.status" => 1])
                        ->count(); // 评论次数
                $item["viewCount"] = CourseCatalogModel::query()->from(CourseCatalogModel::query()->getModel()->getTable()." as cc")
                    ->leftJoin(VodVideoModel::query()->getModel()->getTable()." as v", "v.id", "=", "cc.video_id")
                    ->where(["cc.course_id" => $item["id"], "cc.status" => '1'])
                    ->sum("v.view_count"); // 播放次数
            }
        }
        $this->returnData["data"] = $data;
        return $this->return_result($this->returnData);
    }

    // 课程详情
    public function getCourseDetail(Request $request){
        if($this->returnData["code"] !== 0){
            return $this->return_result($this->returnData);
        }
        if(!$request->id){
            return $this->return_result(ErrorCode::code("params_not_exist", "课程ID"));
        }
        $filter = ["c.id" => $request->id, "c.mall_id" => $request->mallData["id"]];
        $settingData = VideoSettingModel::getFields("operate_mode,open_member,member_discount", ["mall_id" => $request->mallData["id"]]);
        if($settingData["operateMode"] == '1'){
            $broadcasterId = BroadcasterModel::getValue("id", ["mall_id" => $request->mallData["id"], "status" => 1]);
            $filter["c.broadcaster_id"] = ($broadcasterId ?: 0);
        }
        $subSql = CourseCatalogModel::query()->selectRaw("count(*)")->whereRaw("course_id = c.id and status = '1'")->toSql();
        $data = CourseModel::query()->from(CourseModel::query()->getModel()->getTable()." as c")
            ->with(["broadcaster" => function($query){
                $table = BroadcasterModel::query()->getModel()->getTable();
                $query->select("{$table}.id", "{$table}.name", "{$table}.avatar_id", "{$table}.desc");
            }])
            ->where($filter)
            ->select("c.*")->selectRaw("({$subSql}) as currentNum")
            ->first();
        if(!empty($data)) {
            $data = UpTools::transferFields($data->toArray());
            $data["coverImgUrl"] = UpTools::processingPictures($data["coverImgId"]);
            $data["commentCount"] = CommentModel::getCount(["belong_id" => $data["id"], "type" => 2, "status" => 1, "mall_id" => $request->mallData["id"]]) +
                ReplyModel::query()->from(ReplyModel::query()->getModel()->getTable() . " as r")
                    ->leftJoin(CommentModel::query()->getModel()->getTable() . " as c", "c.id", '=', "r.comment_id")
                    ->where(["c.belong_id" => $data["id"], "r.status" => 1])
                    ->count(); // 评论次数
            $data["viewCount"] = CourseCatalogModel::query()->from(CourseCatalogModel::query()->getModel()->getTable()." as cc")
                ->leftJoin(VodVideoModel::query()->getModel()->getTable()." as v", "v.id", "=", "cc.video_id")
                ->where(["cc.course_id" => $data["id"], "cc.status" => "1"])
                ->sum("v.view_count"); // 播放次数
            $request->token && $userId = $this->getTokenVar($request->token, "id");
            $data["type"] = 2; // 课程视频
            $data["subscribe"] = 0; // 0 - 未收藏 1 - 已收藏
            $data["broadcaster"] = BroadcasterModel::transferField($data["broadcaster"]);
            if($data["payMode"] != '0'){
                $data["memberPayMoney"] = CommonServer::price_format($data["payMoney"]);
                $data["userFreeWatch"] = 0;
            }else{
                $data["memberPayMoney"] = CommonServer::price_format(0); // 支付价格
                $data["userFreeWatch"] = 1; // 1 - 免费看 ； 0 - 需付费
            }
            if(!empty($userId)){
                if(CourseCollectModel::query()->where(["course_id" => $data["id"], "user_id" => $userId])->count()){
                    $data["subscribe"] = 1; // 是否收藏
                }
                if($data["payMode"] != '0'){ // 付费
                    $orderExist = OrderModel::query()->where(["user_id" => $userId, "mall_id" => $request->mallData["id"], "type" => 2, "belong_id" => $data["id"]])
                        ->whereIn("status", [2,4,5])
                        ->count();
                    if ($orderExist) {
                        $data["userFreeWatch"] = 1;
                    }else {
                        $userData = VideoUserModel::getFields("level_id,level_time", ["id" => $userId], true, false);
                        if ($data["payMode"] == '1' && $settingData["openMember"] == '1') { // 收费模式  必须开启会员
                            if ($data["memberMode"] == '0') { // memberMode ：0免费，1折扣
                                if (!empty($userData["levelId"]) && $userData["levelTime"] > time()) {
                                    $data["userFreeWatch"] = 1;
                                }
                                $data["memberPayMoney"] = CommonServer::price_format(0);
                            } elseif (!empty($settingData["memberDiscount"])) { // 折扣价
                                $data["memberPayMoney"] = CommonServer::price_format($data["memberPayMoney"] * $settingData["memberDiscount"] / 100);
                            }
                        } elseif ($data["payMode"] == '2') { // 会员免费
                            if (!empty($userData["levelId"]) && $userData["levelTime"] > time()) {
                                $data["userFreeWatch"] = 1;
                            }
                            if ($settingData["openMember"] == '1') {
                                $data["memberPayMoney"] = CommonServer::price_format(0);
                            }
                        }
                    }
                }
                if(empty($videoId = $request->videoId)) {
                    $recordData = CourseViewRecordModel::getFields("id,video_id", ["user_id" => $userId, "course_id" => $data["id"]], true, false);
                    if (empty($recordData["videoId"])) {
                        $videoId = CourseCatalogModel::query()->where("course_id", $data["id"])->orderBy("created_at", "asc")->value("video_id");
                    } else {
                        $videoId = $recordData["videoId"];
                    }
                }
            }else{
                if(empty($videoId = $request->videoId)) {
                    $videoId = CourseCatalogModel::query()->where("course_id", $data["id"])->orderBy("created_at", "asc")->value("video_id");
                }
            }
            if(!empty($data["videoData"] = VodVideoModel::getFields("*", ["id" => $videoId]))){
                if($data["userFreeWatch"] == 0 && !$data["videoData"]["tryTime"]){ // 付费 且没有试看时长
                    $data["videoData"] = '';
                }else {
                    if ($data["userFreeWatch"] == 1) { // 免费看
                        $data["videoData"]["tryTime"] = 0;
                    }
                    $data["videoData"]["viewStatus"] = $data["userFreeWatch"] == "1" ? 1 : ($data["videoData"]["tryTime"] ? 2 : 3); // 1 - 免费；2 - 试看；3 - 付费
                    if (!empty($userId)) {
                        if (empty($recordData)) { // 记录观看课程
                            CourseViewRecordModel::toAdd(["user_id" => $userId, "course_id" => $data["id"], "video_id" => $videoId]);
                        } else {
                            CourseViewRecordModel::doUpdate(["created_at" => Carbon::now(), "video_id" => $videoId], ["id" => $recordData["id"]]);
                        }
                        if(empty(DataCacheModel::getValue(DataCacheModel::$userWatchMark . "_{$videoId}_" . $userId))) { // 一个用户只能记录一次观看次数
                            VodVideoModel::doUpdate(["view_count" => DB::raw("view_count+1")], ["id" => $videoId]);
                            DataCacheModel::saveCache(["key" => DataCacheModel::$userWatchMark . "_{$videoId}_" . $userId, "value" => true]);
                        }
                    }
                    if(!empty($data["videoData"]["videoUrlList"])) {
                        foreach ($data["videoData"]["videoUrlList"] as &$item) {
                            $item["url"] = VodHandle::getInstance()->getUrlBySign($item["url"], $data["videoData"]["videoDuration"], $data["videoData"]["tryTime"]);
                        }
                    }
                    $data["videoData"]["mediaUrl"] = VodHandle::getInstance()->getUrlBySign($data["videoData"]["mediaUrl"], $data["videoData"]["videoDuration"], $data["videoData"]["tryTime"]);
                }
            }else{
                $data["videoData"] = "";
            }
        }else{
            $data = [];
        }
        $this->returnData["data"] = $data;
        return $this->return_result($this->returnData);
    }

    // 课程目录列表
    public function getCourseCatalogList(Request $request){
        if($this->returnData["code"] !== 0){
            return $this->return_result($this->returnData);
        }
        if(!$request->id){
            return $this->return_result(ErrorCode::code("params_not_exist", "课程ID"));
        }
        $filter = ["cc.course_id" => $request->id, "v.mall_id" => $request->mallData["id"], "cc.status" => "1"];
        $settingData = VideoSettingModel::getFields("operate_mode,open_member", ["mall_id" => $request->mallData["id"]]);
        if($settingData["operateMode"] == '1'){
            $broadcasterId = BroadcasterModel::getValue("id", ["mall_id" => $request->mallData["id"], "status" => 1]);
            $filter["v.broadcaster_id"] = ($broadcasterId ?: 0);
        }
        $page = $request->page ?: 1;
        $pageSize = $request->pageSize ?: 10;
        $db = CourseCatalogModel::query()->from(CourseCatalogModel::query()->getModel()->getTable()." as cc")
            ->leftJoin(VodVideoModel::query()->getModel()->getTable()." as v", "v.id", "=", "cc.video_id")
            ->where($filter)
            ->orderBy("cc.created_at", "asc");
        $data['count'] = $db->count();
        $data['currentPage'] = $page;
        $data['totalPage'] = ceil(($data['count'])/$pageSize);
        if(!empty($request->videoId)){ // 直接加载到这个视频id这页
            $temp = $db->select(["v.id"])->get()->toArray();
            if(!empty($temp)) {
                $temp = array_column($temp, "id");
                $size = array_search($request->videoId, $temp) + 1;
                $page = 1;
                $data['currentPage'] = ceil($size/$pageSize);
                $pageSize = $data['currentPage'] * $pageSize;
            }
        }
        $data["list"] = $db->select(["v.id","v.title","v.cover_img_id","v.desc","v.view_count","v.video_length",'v.create_time',"v.try_time", "v.file_type"])
            ->skip(($page - 1) * $pageSize)->take($pageSize)
            ->get()->toArray();
        if(!empty($data["list"])){
            $data["list"] = VodVideoModel::transferField($data["list"]);
            $courseData = CourseModel::getFields("pay_mode,member_mode", ["id" => $request->id], true, false);
            $request->token && $userId = $this->getTokenVar($request->token, "id");
            if(!empty($userId)) {
                $userData = VideoUserModel::getFields("level_id,level_time", ["id" => $userId], true, false);
            }
            if($courseData["payMode"] != '0'){ // 付费
                $userFreeWatch = false;
                if(!empty($userId)) {
                    $orderExist = OrderModel::query()->where(["user_id" => $userId, "mall_id" => $request->mallData["id"], "type" => 2, "belong_id" => $request->id])
                        ->whereIn("status", [2, 4, 5])
                        ->count();
                    if ($orderExist) {
                        $userFreeWatch = true;
                    }
                }
                if(!$userFreeWatch && $settingData["openMember"] == '1' && !empty($userData["levelId"]) && $userData["levelTime"] > time()) {
                    if ($courseData["payMode"] == '1' && $courseData["memberMode"] == '0') { // 收费模式   memberMode ：0免费，1折扣
                        $userFreeWatch = true;
                    } elseif ($courseData["payMode"] == '2') {
                        $userFreeWatch = true;
                    }
                }
            }else{
                $userFreeWatch = true;
            }
            foreach ($data["list"] as &$item){
                $item["createTime"] = substr($item["createTime"], 0, 10);
                $item["viewStatus"] = $userFreeWatch ? 1 : ($item["tryTime"] ? 2 : 3); // 1 - 免费；2 - 试看；3 - 付费
            }
        }
        $this->returnData["data"] = $data;
        return $this->return_result($this->returnData);
    }

    // 收藏或者取消收藏课程
    public function toCollectCourse(Request $request){
        if($this->returnData["code"] !== 0){
            return $this->return_result($this->returnData);
        }
        if(!$request->id){
            return $this->return_result(ErrorCode::code("params_not_exist", "课程ID"));
        }
        if(!CourseModel::query()->where("id", $request->id)->count()){
            return $this->return_result(ErrorCode::code("customized", "课程不存在"));
        }
        $data = CourseCollectModel::getFields("id", ["course_id" => $request->id, "user_id" => $request->userLoginData["id"]], true, false);
        if(!empty($data)){
            CourseCollectModel::delByFilter(["id" => $data["id"]]);
            $this->returnData["msg"] = "取消收藏成功";
        }else{
            CourseCollectModel::toAdd(["course_id" => $request->id, "user_id" => $request->userLoginData["id"]]);
            $this->returnData["msg"] = "收藏成功";
        }
        return $this->return_result($this->returnData);
    }

    // 课程观看记录
    public function getCourseViewRecord(Request $request){
        if($this->returnData["code"] !== 0){
            return $this->return_result($this->returnData);
        }
        $page = $request->page ?: 1;
        $pageSize = $request->pageSize ?: 10;
        $db = CourseViewRecordModel::query()->from(CourseViewRecordModel::query()->getModel()->getTable()." as cvr")
            ->leftJoin(CourseModel::query()->getModel()->getTable()." as c", "cvr.course_id", "=", "c.id")
            ->where(["cvr.user_id" => $request->userLoginData["id"], "cvr.mall_id" => $request->mallData["id"]]);
        $data['count'] = $db->count();
        $data['currentPage'] = $page;
        $data['totalPage'] = ceil(($data['count'])/$pageSize);
        $data["list"] = $db->leftJoin(VodVideoModel::query()->getModel()->getTable()." as v", "cvr.video_id", "=", "v.id")
            ->select("c.id", "c.name", "c.broadcaster_id", "c.cover_img_id", "v.title as videoTitle", "v.id as videoId")
            ->orderBy("cvr.created_at", "desc")
            ->get()->toArray();
        if(!empty($data["list"])){
            $data["list"] = CourseModel::transferField($data["list"]);
            foreach ($data["list"] as &$item){
                $item["videoTitle"] = $item["videoTitle"] ?: "";
                $item["videoId"] = $item["videoId"] ?: 0;
                $catalogData = CourseCatalogModel::query()->select("video_id")
                    ->where(["course_id" => $item["id"], "status" => "1"])
                    ->orderBy("created_at", "asc")
                    ->get()->toArray();
                $item["currentNum"] = count($catalogData);
                foreach ($catalogData as $key => $catalog){
                    if($catalog["video_id"] == $item["videoId"]){
                        $item["no"] = $key;
                    }
                }
            }
        }
        $this->returnData["data"] = $data;
        return $this->return_result($this->returnData);
    }

    // 已购买的课程列表
    public function getPayedCourseList(Request $request){
        if($this->returnData["code"] !== 0){
            return $this->return_result($this->returnData);
        }
        $page = $request->page ?: 1;
        $pageSize = $request->pageSize ?: 10;
        $db = OrderModel::query()->from(OrderModel::query()->getModel()->getTable()." as o")
            ->leftJoin(CourseModel::query()->getModel()->getTable()." as c", "o.belong_id", "=", "c.id")
            ->where(["o.user_id" => $request->userLoginData["id"], "o.mall_id" => $request->mallData["id"], "type" => 2])
            ->whereIn("o.status", [2,4,5]);
        $data['count'] = $db->count();
        $data['currentPage'] = $page;
        $data['totalPage'] = ceil(($data['count'])/$pageSize);
        $subSql = CourseCatalogModel::query()->selectRaw("count(*)")->whereRaw("course_id = c.id and status = '1'")->toSql();
        $data["list"] = $db->select("c.id", "c.name", "c.broadcaster_id", "c.cover_img_id", "c.number", "o.pay_time as buyTime")
            ->selectRaw("({$subSql}) as currentNum")
            ->orderBy("o.pay_time", "desc")
            ->get()->toArray();
        if(!empty($data["list"])){
            $data["list"] = CourseModel::transferField($data["list"]);
            foreach ($data["list"] as &$item){
                $item["buyTime"] = substr($item["buyTime"], 0, 10);
                $viewRecordData = CourseViewRecordModel::query()->from(CourseViewRecordModel::query()->getModel()->getTable()." as cvr")
                    ->leftJoin(VodVideoModel::query()->getModel()->getTable()." as v", "cvr.video_id", "=", "v.id")
                    ->select("v.title", "v.id")
                    ->where("cvr.course_id", $item["id"])->first();
                $item["videoTitle"] = !empty($viewRecordData->title) ? $viewRecordData->title : "";
                $item["videoId"] = !empty($viewRecordData->id) ? $viewRecordData->id : "";
            }
        }
        $this->returnData["data"] = $data;
        return $this->return_result($this->returnData);
    }

    // 我收藏的课程
    public function getCollectCourse(Request $request){
        if($this->returnData["code"] !== 0){
            return $this->return_result($this->returnData);
        }
        $page = $request->page ?: 1;
        $pageSize = $request->pageSize ?: 10;
        $db = CourseCollectModel::query()->from(CourseCollectModel::query()->getModel()->getTable()." as cc")
            ->leftJoin(CourseModel::query()->getModel()->getTable()." as c", "cc.course_id", "=", "c.id")
            ->where(["cc.user_id" => $request->userLoginData["id"], "cc.mall_id" => $request->mallData["id"]]);
        $data['count'] = $db->count();
        $data['currentPage'] = $page;
        $data['totalPage'] = ceil(($data['count'])/$pageSize);
        $data["list"] = $db->select("c.id", "c.name", "c.broadcaster_id", "c.cover_img_id", "c.number", "cc.created_at as collectTime")
            ->orderBy("cc.created_at", "desc")
            ->get()->toArray();
        if(!empty($data["list"])){
            $data["list"] = CourseModel::transferField($data["list"]);
            foreach ($data["list"] as &$item){
                $item["collectTime"] = substr($item["collectTime"], 0, 10);
                $catalogData = CourseCatalogModel::query()->select("video_id")
                    ->where(["course_id" => $item["id"], "status" => "1"])
                    ->orderBy("created_at", "asc")
                    ->get()->toArray();
                $item["currentNum"] = count($catalogData);
                $viewRecordData = CourseViewRecordModel::query()->from(CourseViewRecordModel::query()->getModel()->getTable()." as cvr")
                    ->leftJoin(VodVideoModel::query()->getModel()->getTable()." as v", "cvr.video_id", "=", "v.id")
                    ->select("v.title", "v.id")
                    ->where("cvr.course_id", $item["id"])->first();
                $item["videoTitle"] = !empty($viewRecordData->title) ? $viewRecordData->title : "";
                $item["videoId"] = !empty($viewRecordData->id) ? $viewRecordData->id : "";
                foreach ($catalogData as $key => $catalog){
                    if($catalog["video_id"] == $item["videoId"]){
                        $item["no"] = $key;
                    }
                }
            }
        }
        $this->returnData["data"] = $data;
        return $this->return_result($this->returnData);
    }
}